Signal Quality Indicators for breathing signal
Copyright (C) 2022 Miodrag Bolic
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details <https://www.gnu.org/licenses/>.
Dependencies: files PEX_T1.mat, Free_T1.mat and Irregular_T1.mat. Code: br_rate_est.m
Acknowledgements
This notebook uses data from the database described in the paper: Shafiq, G., Veluvolu, K. Multimodal chest surface motion data for respiratory and cardiovascular monitoring applications. Sci Data 4, 170052 (2017). https://doi.org/10.1038/sdata.2017.52 % Changing the path from main_folder to a particular chapter
main_path=fileparts(which('Main_Content.mlx'));
%addpath(append(main_path,'/Chapter2'))
cd (append(main_path,'/Chapter9/Signal Quality'))
addpath(append(main_path,'/Service'))
SAVE_FLAG=0; % saving the figures in a file
Introduction
In this notebook, we are going to load respiratory belt and temperature sensor data and to show the waveforms as well as to compute several signal quality indicators.
Loading breathing data
% Loading breathing data obtained after exercize
t=1/fs:1/fs:length(mp36_s(1,:))/fs;
[m,i_max]=findpeaks(mp36_s(4,lim));
[m,i_min]=findpeaks(-mp36_s(4,lim));
plot(t(lim)-t(lim(1)),smooth(mp36_s(2,lim),25))
plot([i_all(i)/fs, i_all(i)/fs],ylim.*ones(1,2),'b')
text(i_min/fs,-1*ones(1,length(i_min)),'Expiration')
text(i_max(1:end-1)/fs,ones(1,length(i_max(1:end-1))),'Inspiration')
title('Breathing signal from the respiratory belt')
plot(t(lim)-t(lim(1)),mp36_s(4,lim))
ylabel('\DeltaT (degrees)')
title('Breathing signal from the temperature sensor')
plot([i_all(i)/fs, i_all(i)/fs],ylim.*ones(1,2),'b')
exportgraphics(gcf,"Fig9.3.jpg", 'Resolution',600)
%text(i_min/fs,ylim*ones(1,length(i_min)),'expiration')
%text(i_max/fs,-ylim*ones(1,length(i_max)),'inspiration')
SQI
Loading signal after exercise
t=1/fs:1/fs:length(mp36_s(1,:))/fs;
% Define frequency ranges of interest fot the signal
Fmask_low_sig=br_rate_est(resp',fs)/60-0.1;
Fmask_high_sig=br_rate_est(resp',fs)/60+0.1;
Nfft = (60*2*NyquistF)/FResBPM; %number of bins in power spectrum
[Pxx,F] = periodogram(resp,hamming(length(resp)),Nfft,fs);
% Compute power in the frequency band of the signal of interest
FMask1 = (F >= Fmask_low_sig)&(F <= Fmask_high_sig);
PowerSig = sum(Pxx(FMask1));
% Compute power in the total frequency band
FMask2 = (F >= Fmask_low_all)&(F <= Fmask_high_all);
PowerAll = sum(Pxx(FMask2));
% Compute signal quality indices = ratio of the power in the
PowerRatio=PowerSig/PowerAll;
if PowerRatio < 0.9 && PowerRatio > 0.5
% ylabel('Amplitude(mV)')
% title('Signal from respiratory belt')
ylabel('\DeltaT (degrees)')
title('Breathing signal from the temperature sensor after exercise')
annonation_save('a)',"Fig9.4a.jpg", SAVE_FLAG);
[normalizedACF, lags] = autocorr(resp, 'NumLags',1000,'NumSTD',2);
plot(lags/fs,normalizedACF)
ylabel('Sample autocorrelation')
title('Sample autocorrelation function of the signal in Fig9.4a)')
annonation_save('b)',"Fig9.4b.jpg", SAVE_FLAG);
Loading irregular breathing signal
t=1/fs:1/fs:length(mp36_s(1,:))/fs;
% Define frequency ranges of interest fot the signal
Fmask_low_sig=br_rate_est(resp',fs)/60-0.1;
Fmask_high_sig=br_rate_est(resp',fs)/60+0.1;
Nfft = (60*2*NyquistF)/FResBPM; %number of bins in power spectrum
[Pxx,F] = periodogram(resp,hamming(length(resp)),Nfft,fs);
% Compute power in the frequency band of the signal of interest
FMask1 = (F >= Fmask_low_sig)&(F <= Fmask_high_sig);
PowerSig = sum(Pxx(FMask1));
% Compute power in the total frequency band
FMask2 = (F >= Fmask_low_all)&(F <= Fmask_high_all);
PowerAll = sum(Pxx(FMask2));
% Compute signal quality indices = ratio of the power in the
PowerRatio=PowerSig/PowerAll;
if PowerRatio < 0.9 && PowerRatio > 0.5
% ylabel('Amplitude(mV)')
% title('Signal from respiratory belt')
ylabel('\DeltaT (degrees)')
title('Signal from the temperature sensor during irregular breathing')
annonation_save('c)',"Fig9.4c.jpg", SAVE_FLAG);
[normalizedACF, lags] = autocorr(resp, 'NumLags',1000,'NumSTD',2);
plot(lags/fs,normalizedACF)
ylabel('Sample autocorrelation')
title('Sample autocorrelation function of the signal in Fig9.4c)')
annonation_save('d)',"Fig9.4d.jpg", SAVE_FLAG);
Exersizes
Excersize 1: Show ACF for cases when respiratory belt waveform is selected instead of thermal sensor waveform.
Excersize 2: Instead of loading waveform obtained after exercise from the file 'PEX_T1.mat', load the waveform 'Free_T1.mat' that corresponds to the free breathing signal. Compute PowerRatio and show ACF. Why is the quality lower than in the case of the waveform after exercise?
Excersize 3: How does the length of the signal affects the PowerRatio and ACF. Reduce signals to 60 sec.